package com.xxwy.spring.event;

import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ApplicationEventMulticaster;
import org.springframework.context.event.ContextClosedEvent;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericApplicationContext;
import org.springframework.scheduling.concurrent.CustomizableThreadFactory;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 异步event处理器.
 *
 * @author xxwy
 * @date 2021/9/21 0021
 */
public class AsyncEventSpringEventDemo {

    public static void main(String[] args) {
        GenericApplicationContext applicationContext = new GenericApplicationContext();
        applicationContext.addApplicationListener(new MyEventListener());
        applicationContext.refresh();

        ApplicationEventMulticaster multicaster = applicationContext.getBean(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME,
                ApplicationEventMulticaster.class);
        if (multicaster instanceof SimpleApplicationEventMulticaster) {
            SimpleApplicationEventMulticaster eventMulticaster = (SimpleApplicationEventMulticaster) multicaster;
            ExecutorService executorService = Executors.newSingleThreadExecutor(new CustomizableThreadFactory("my-spring-event-thread-pool"));

            // 异步执行event
            eventMulticaster.setTaskExecutor(executorService);

            // contextCloseEvent-->线程池关闭
            applicationContext.addApplicationListener(new ApplicationListener<ContextClosedEvent>() {
                @Override
                public void onApplicationEvent(ContextClosedEvent event) {
                   if (!executorService.isShutdown()) {
                       executorService.shutdown();
                   }
                }
            });
        }

        applicationContext.publishEvent(new MySpringEvent("你好"));
        applicationContext.close();
    }
}
